﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ClientOverflow.DataObjects;
using ClientOverflow.DataTransferObjects;
using Answer = ClientOverflow.DataTransferObjects.Answer;
using Department = ClientOverflow.DataObjects.Department;
using Question = ClientOverflow.DataTransferObjects.Question;
using Tag = ClientOverflow.DataObjects.Tag;
using User = ClientOverflow.DataTransferObjects.User;

namespace ClientOverflow.CommunicationServices.Data
{
    /// <summary>
    /// DataObjectsConversionExtensions is a class implementing extension methods for converting DataObject
    /// types to DTO types. All the methods are extension methods so the data objects don't have to know the
    /// DTO objects into which they are converted.
    /// </summary>
    internal static class DataObjectsConversionExtensions
    {
        internal static User ToDto(this DataObjects.User matchingDbUser)
        {
            return new User()
                       {
                           Email = matchingDbUser.Email,
                           Name = matchingDbUser.Name,
                           Department = matchingDbUser.Department.ToDto(),
                           Password = matchingDbUser.Password,
                           Questions = matchingDbUser.Questions.Select(question => question.ToDto()).ToList(),
                           Answers = matchingDbUser.Answers.Select(answer => answer.ToDto()).ToList()
                       };
        }

        internal static Question ToDto(this DataObjects.Question question)
        {
            var dtoQuestion = new Question
                          {
                              ID = question.ID,
                              Title = question.Title,
                              Content = question.Content,
                              Tags = new List<DataTransferObjects.Tag>(question.Tags.Select(tag => tag.ToDto())),
                              Answers = question.Answers.Select(dbAnswer => dbAnswer.ToDto()).ToList(),
                              CorrectAnswerID = question.CorrectAnswerID,
                              UpVotes = question.UpVotes.Select(dbUpVote => dbUpVote.ToDto()).ToList(),
                              DownVotes = question.DownVotes.Select(dbDownVote => dbDownVote.ToDto()).ToList()
                          };
            
            return dtoQuestion;
        }

        private static Answer ToDto(this DataObjects.Answer dbAnswer)
        {
            var dtoAnswer = new Answer
                                {
                                    ID = dbAnswer.ID,
                                    Content = dbAnswer.Content,
                                    UpVotes = dbAnswer.UpVotes.Select(vote => vote.ToDto()).ToList(),
                                    DownVotes = dbAnswer.DownVotes.Select(vote => vote.ToDto()).ToList()
                                };

            return dtoAnswer;
        }

        internal static DataTransferObjects.Tag ToDto(this Tag dbTag)
        {
            return new DataTransferObjects.Tag
                       {
                           Name = dbTag.Name
                       };
        }

        private static DataTransferObjects.Department ToDto(this Department dbDepartment)
        {
            return new DataTransferObjects.Department
                       {
                           Name = dbDepartment.Name
                       };
        }

        private static Vote ToDto<T>(this QuestionVote<T> vote)
        {
            return new Vote();
        }

        private static Vote ToDto<T>(this AnswerVote<T> vote)
        {
            return new Vote();
        }
    }
}